package com.smedi.ismedi.authoritymanagement.core.port.adapter.persistence.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.Role;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RoleAssignment;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RoleBasic;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RoleMember;
import com.smedi.ismedi.authoritymanagement.core.domain.dto.RoleAssignmentQuery;
import com.smedi.ismedi.authoritymanagement.core.domain.dto.RoleQuery;
import com.smedi.ismedi.authoritymanagement.core.domain.repository.RoleBasicRepository;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.persistence.model.RoleBasicEntity;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.persistence.model.RoleMemberEntity;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.persistence.mybatis.mapper.RoleBasicMapper;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.persistence.mybatis.mapper.RoleMemberMapper;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.List;

@Slf4j
@Repository
@AllArgsConstructor
public class RoleBasicRepositoryImpl extends ServiceImpl<RoleBasicMapper, RoleBasicEntity> implements RoleBasicRepository, IService<RoleBasicEntity> {
    private final DozerUtil dozerUtil;
    private final AdapterConverter adapterConverter;

    @Override
    public RoleBasic selectByRoleId(Long roleId) {
        RoleBasicEntity row = this.getBaseMapper().selectById(roleId);
        return dozerUtil.convertor(row, RoleBasic.class);
    }

    @Override
    public List<RoleBasic> selectByRoleIds(List<Long> roleIds) {
        QueryWrapper<RoleBasicEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", roleIds);
        List<RoleBasicEntity> roleBasicEntities = this.getBaseMapper().selectList(queryWrapper);
        return dozerUtil.convertor(roleBasicEntities, RoleBasic.class);
    }

    @Override
    public int selectRoleNameCount(String roleName, Long roleId) {
        QueryWrapper<RoleBasicEntity> wrapper = new QueryWrapper();
        wrapper.eq("role_name", roleName.trim());
        if (roleId != null) {
            wrapper.ne("id", roleId);
        }
        return this.getBaseMapper().selectCount(wrapper);
    }

    @Override
    public RoleBasic doInsert(RoleBasic data) {
        RoleBasicEntity roleBasicEntity = dozerUtil.convertor(data, RoleBasicEntity.class);
        this.getBaseMapper().insert(roleBasicEntity);
        return dozerUtil.convertor(roleBasicEntity, RoleBasic.class);
    }

    @Override
    public RoleBasic doUpdate(RoleBasic data) {
        RoleBasicEntity roleBasicEntity = dozerUtil.convertor(data, RoleBasicEntity.class);
        this.getBaseMapper().updateById(roleBasicEntity);
        return dozerUtil.convertor(roleBasicEntity, RoleBasic.class);
    }

    @Override
    public void doDeleteByRoleId(Long roleId) {
        QueryWrapper<RoleBasicEntity> wrapper = new QueryWrapper();
        wrapper.eq("id", roleId);

        this.getBaseMapper().delete(wrapper);
    }

    @Override
    public List<RoleBasic> selectByRoleName(String roleName, boolean fuzzy) {
        QueryWrapper<RoleBasicEntity> wrapper = new QueryWrapper();
        if (fuzzy) {
            wrapper.like("role_name", roleName);
        } else {
            wrapper.eq("role_name", roleName);
        }

        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), RoleBasic.class);
    }

    @Override
    public List<Role> getRoleList(RoleQuery roleQuery) {
        LambdaQueryWrapper<RoleBasicEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(roleQuery.getIds()), RoleBasicEntity::getId, roleQuery.getIds());
        lambdaQueryWrapper.in(StringUtils.isNotBlank(roleQuery.getName()), RoleBasicEntity::getRoleName, roleQuery.getName());
        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(roleQuery.getNames()), RoleBasicEntity::getRoleName, roleQuery.getNames());

        List<RoleBasicEntity> roleBasicEntities = this.getBaseMapper().selectList(lambdaQueryWrapper);

        return adapterConverter.roleBasicEntityToRole(roleBasicEntities);
    }

    @Override
    public List<Role> getRoleListWithoutToken(RoleQuery roleQuery) {
        LambdaQueryWrapper<RoleBasicEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(roleQuery.getIds()), RoleBasicEntity::getId, roleQuery.getIds());
        lambdaQueryWrapper.in(StringUtils.isNotBlank(roleQuery.getName()), RoleBasicEntity::getRoleName, roleQuery.getName());
        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(roleQuery.getNames()), RoleBasicEntity::getRoleName, roleQuery.getNames());

        List<RoleBasicEntity> roleBasicEntities = this.getBaseMapper().selectList(lambdaQueryWrapper);

        return adapterConverter.roleBasicEntityToRole(roleBasicEntities);
    }
}
